home *** CD-ROM | disk | FTP | other *** search
/ Euroscene 2 / Euroscene 2.iso / USEFUL / DeliTracker130 / Developer / Developer.run / Examples / IFF-8SVX.s < prev    next >
Encoding:
Text File  |  1992-09-23  |  16.4 KB  |  718 lines

  1.  
  2.     opt o-,d-
  3.  
  4.     incdir    "Includes:"
  5.     include    "misc/DevpacMacros.i"
  6.     include    "misc/DeliPlayer.i"
  7.     include    "exec/exec.i"
  8.     include    "exec/io.i"
  9.     include    "devices/audio.i"
  10.  
  11.  
  12. Left_0        EQU 1                ; Audiokanal 1
  13. Right_1        EQU 2                ; Audiokanal 2
  14. Right_2        EQU 4                ; Audiokanal 3
  15. Left_3        EQU 8                ; Audiokanal 4
  16.  
  17. FORM        EQU ('F'<<24)!('O'<<16)!('R'<<8)!('M')
  18. ID_8SVX        EQU ('8'<<24)!('S'<<16)!('V'<<8)!('X')
  19. ID_VHDR        EQU ('V'<<24)!('H'<<16)!('D'<<8)!('R')
  20. ID_CHAN        EQU ('C'<<24)!('H'<<16)!('A'<<8)!('N')
  21. ID_SEQN        EQU ('S'<<24)!('E'<<16)!('Q'<<8)!('N')
  22. ID_FADE        EQU ('F'<<24)!('A'<<16)!('D'<<8)!('E')
  23. ID_BODY        EQU ('B'<<24)!('O'<<16)!('D'<<8)!('Y')
  24.  
  25. sCmpNone    EQU 0
  26.  
  27. sCompression    EQU 15
  28. samplesPerSec    EQU 12
  29.  
  30. sampletype    EQU 0
  31. LEFT        EQU 2
  32. RIGHT        EQU 4
  33. STEREO        EQU 6
  34.  
  35.  
  36. *-----------------------------------------------------------------------*
  37.  
  38.     STRUCTURE    DeliPlayMsg,MN_SIZE
  39.     APTR    dpm_Command
  40.     LONG    dpm_UserData
  41.     LABEL    dpm_SIZEOF
  42.  
  43. *-----------------------------------------------------------------------*
  44.  
  45.  
  46. ;
  47. ;
  48.     SECTION Player,Code
  49. ;
  50. ;
  51.  
  52.     PLAYERHEADER PlayerTagArray
  53.  
  54.     dc.b '$VER: IFF-8SVX player module V1.3 (08 Apr 92)',0
  55.     even
  56.  
  57. PlayerTagArray
  58.     dc.l    DTP_PlayerVersion,2
  59.     dc.l    DTP_PlayerName,PName
  60.     dc.l    DTP_Creator,CName
  61.     dc.l    DTP_Check2,Chk
  62.     dc.l    DTP_InitPlayer,InitPlay
  63.     dc.l    DTP_EndPlayer,EndPlay
  64.     dc.l    DTP_StartInt,StartSnd
  65.     dc.l    DTP_StopInt,StopSnd
  66.     dc.l    DTP_Volume,SetVol
  67.     dc.l    DTP_Balance,SetVol
  68.     dc.l    TAG_DONE
  69.  
  70. *-----------------------------------------------------------------------*
  71. ;
  72. ; Player/Creatorname und lokale Daten
  73.  
  74. PName        dc.b 'IFF-8SVX',0
  75.  
  76. CName        dc.b 'Frank Riffel and Peter Kunath in 1992',0
  77.  
  78. TaskName    dc.b 'IFF-8SVX_Player',0
  79. DeliPortName    dc.b '8SVX->Player',0
  80. PlayerPortName    dc.b '8SVX<-Player',0
  81. AudioPortName    dc.b '8SVX_Player',0
  82. audioname    dc.b 'audio.device',0
  83. ChannelMap    dc.b Left_0!Right_1
  84.         dc.b Left_0!Right_2
  85.         dc.b Left_3!Right_1
  86.         dc.b Left_3!Right_2
  87.     even
  88.  
  89. _DOSBase    dc.l 0
  90. SongendPtr    dc.l 0
  91. QuitFlag    dc.w 0
  92.  
  93. s_adr        dc.l 0            ; Startaddress
  94. s_end        dc.l 0            ; Endaddress
  95. s_size        dc.l 0            ; Samplesize
  96. s_speed        dc.w 0            ; Initial Speed
  97. s_chan1        dc.l 0            ; channel 1
  98. s_chan2        dc.l 0            ; channel 2
  99.  
  100. p_chmap        dc.l 0            ; channelmap
  101. p_size        dc.l 0            ; Samplesize
  102. p_pos        dc.l 0            ; Position in sample
  103. p_len        dc.l 0            ; Length of sampleblock
  104. p_speed        dc.w 0            ; see above ... for playing
  105. p_chan1        dc.l 0            ; channel 1
  106. p_chan2        dc.l 0            ; channel 2
  107. p_l_vol        dc.w 0            ; left volume
  108. p_r_vol        dc.w 0            ; right volume
  109. p_wmsg        dc.w 0            ; write message counter
  110. p_pause        dc.w 0            ; playing/paused
  111. p_endpos    dc.l 0            ; songend
  112.  
  113. p_ioreq1    dc.l IORequest1a
  114. p_ioreq1b    dc.l IORequest1b
  115. p_ioreq2    dc.l IORequest2a
  116. p_ioreq2b    dc.l IORequest2b
  117.  
  118. PlayerPort    dcb.b MP_SIZE,0
  119. DeliPort    dcb.b MP_SIZE,0
  120.  
  121. DeliMsg        dcb.b dpm_SIZEOF,0
  122.  
  123. AudioPort    dcb.b MP_SIZE,0
  124.  
  125. IORequest    dcb.b ioa_SIZEOF,0
  126. IORequest1a    dcb.b ioa_SIZEOF,0
  127. IORequest1b    dcb.b ioa_SIZEOF,0
  128. IORequest2a    dcb.b ioa_SIZEOF,0
  129. IORequest2b    dcb.b ioa_SIZEOF,0
  130.  
  131. *-----------------------------------------------------------------------*
  132. ;
  133. ; Testet auf IFF 8SVX
  134.  
  135. Chk
  136.     move.l    dtg_ChkData(a5),a0
  137.  
  138.     cmpi.l    #FORM,(a0)+            ; right file type ?
  139.     bne    ChkErr                ; no IFF File at all
  140.     move.l    (a0)+,a1            ; size
  141.     cmp.l    dtg_ChkSize(a5),a1
  142.     bgt    ChkErr                ; file is too small
  143.     add.l    a0,a1                ; calculate last address
  144.     move.l    a1,s_end            ; end address in memory
  145.  
  146.     cmpi.l    #ID_8SVX,(a0)+            ; is it a 8SVX sample file?
  147.     bne    ChkErr                ; no
  148.     move.l    a0,s_adr            ; start address in memory
  149.  
  150.     move.l    #ID_VHDR,d0            ; find VHDR chunk
  151.     move.l    s_adr,a0            ; start address
  152.     move.l    s_end,a1            ; end address
  153.     bsr.s    FindChunk            ; search chunk
  154.     tst.l    d0                ; test result
  155.     beq.s    ChkErr                ; this file must be mangled!
  156.  
  157.     addq.l    #4,a0                ; skip chunk length
  158.     cmpi.b    #sCmpNone,sCompression(a0)    ; is the sample packed?
  159.     bne.s    ChkErr                ; packing is not supported yet
  160.     move.w    samplesPerSec(a0),s_speed    ; samples per second
  161.  
  162.     moveq    #0,d2                ; sample is mono (default)
  163.  
  164.     move.l    #ID_CHAN,d0            ; find CHAN chunk
  165.     move.l    s_adr,a0            ; start address
  166.     move.l    s_end,a1            ; end address
  167.     bsr.s    FindChunk            ; search chunk
  168.     tst.l    d0                ; test result
  169.     beq.s    ChkNoChan            ; sorry, no chan chunk found
  170.  
  171.     addq.l    #4,a0                ; skip chunk length
  172.     cmpi.l    #STEREO,sampletype(a0)        ; type of sample ?
  173.     bne.s    ChkNoChan            ; LEFT and RIGHT are ignored and it
  174.     moveq    #1,d2                ; is played in mono on both speakers
  175. ChkNoChan
  176.     move.l    #ID_BODY,d0            ; find BODY chunk
  177.     move.l    s_adr,a0            ; start address
  178.     move.l    s_end,a1            ; end address
  179.     bsr.s    FindChunk            ; search chunk
  180.     tst.l    d0                ; test result
  181.     beq.s    ChkErr                ; sorry, no body chunk found
  182.  
  183.     move.l    (a0)+,d1            ; chunk size
  184.     lsr.l    d2,d1                ; halfe size if stereo
  185.     move.l    d1,s_size            ; save size of the sample
  186.     move.l    a0,s_chan1            ; waveform data for channel 1
  187.     mulu    d2,d1                ; same data if mono
  188.     add.l    d1,a0                ; add size
  189.     move.l    a0,s_chan2            ; waveform data for channel 2
  190.  
  191.     moveq    #0,d0                ; it is a sample!
  192.     bra.s    ChkEnd
  193. ChkErr
  194.     moveq    #-1,d0                ; not a sample !
  195. ChkEnd
  196.     rts
  197.  
  198. ;-----------------------------------------------------------------------
  199. ;
  200. ; This function finds the given chunk and skips all others in between!
  201. ;
  202. ; in:    d0.l ChunkID
  203. ;    a0.l StartPosition
  204. ;    a1.l LastPosition
  205. ;
  206. ; out:    a0.l ChunkStart if not found NULL
  207.  
  208. FindChunk
  209.     cmp.l    (a0)+,d0            ; is this the searched chunk ?
  210.     beq.s    Found                ; yes !
  211.     adda.l    (a0)+,a0            ; no, then skip this chunk
  212.     cmpa.l    a0,a1                ; are we behind the mem limit ?
  213.     bgt.s    FindChunk            ; no, search until error or success
  214.     suba.l    a0,a0                ; we are behind the limits
  215.     moveq    #0,d0                ; errorflag
  216. Found    rts                    ; exit this routine
  217.  
  218. *-----------------------------------------------------------------------*
  219. ;
  220. ; Init Player
  221.  
  222. InitPlay
  223.     move.l    dtg_DOSBase(a5),_DOSBase    ; DOS
  224.  
  225.     move.l    dtg_SongEnd(a5),SongendPtr    ; store Songend FunctionPtr
  226.  
  227.     lea    PlayerPort(pc),a0        ; init Port
  228.     clr.l    LN_SUCC(a0)
  229.     clr.l    LN_PRED(a0)
  230.     move.b    #NT_MSGPORT,LN_TYPE(a0)
  231.     clr.b    LN_PRI(a0)
  232.     move.l    #PlayerPortName,LN_NAME(a0)
  233.     move.b    #PA_SIGNAL,MP_FLAGS(a0)
  234.  
  235.     moveq    #-1,d0
  236.     CALLEXEC AllocSignal            ; Signalbit für PlayerPort besorgen
  237.     lea    PlayerPort(pc),a1        ; ^Port
  238.     move.b    d0,MP_SIGBIT(a1)
  239.     move.l    ThisTask(a6),MP_SIGTASK(a1)    ; copy ^ThisTask
  240.     CALLEXEC AddPort            ; MsgPort anlegen
  241.  
  242.     move.l    #TaskName,d1            ; name
  243.     moveq    #10,d2                ; pri
  244.     lea    PlayerProc(pc),a0        ; ^segment
  245.     move.l    a0,d3
  246.     lsr.l    #2,d3                ; APTR -> BPTR
  247.     move.l    #4096,d4            ; stack
  248.     CALLDOS CreateProc            ; start a new process
  249.     tst.l    d0
  250.     beq.s    EndPlay2            ; error
  251.  
  252.     lea    PlayerPort(pc),a0
  253.     CALLEXEC WaitPort            ; Schlaf gut
  254.  
  255.     lea    PlayerPort(pc),a0
  256.     CALLEXEC GetMsg
  257.  
  258.     move.l    d0,a0                ; Message
  259.     move.l    dpm_UserData(a0),d0        ; set returnvalue
  260.     bne.s    EndPlay2            ; error
  261.     rts
  262.  
  263. *-----------------------------------------------------------------------*
  264. ;
  265. ; End Player
  266.  
  267. EndPlay
  268.     lea    DeliPort(pc),a0
  269.     lea    DeliMsg(pc),a1
  270.     move.l    #PlayerPort,MN_REPLYPORT(a1)
  271.     move.w    #dpm_SIZEOF,MN_LENGTH(a1)
  272.     move.l    #EndPlayer,dpm_Command(a1)
  273.     CALLEXEC PutMsg
  274.  
  275.     lea    PlayerPort(pc),a0
  276.     CALLEXEC WaitPort            ; Schlaf gut
  277.  
  278.     lea    PlayerPort(pc),a0
  279.     CALLEXEC GetMsg
  280. EndPlay2
  281.     lea    PlayerPort(pc),a1
  282.     CALLEXEC RemPort            ; MsgPort entfernen
  283.     lea    PlayerPort(pc),a1
  284.     move.b    MP_SIGBIT(a1),d0
  285.     CALLEXEC FreeSignal            ; Signalbit für PlayerPort freigeben
  286.  
  287.     moveq    #-1,d0                ; set error
  288.     rts
  289.  
  290. *-----------------------------------------------------------------------*
  291. ;
  292. ; Start Sound
  293.  
  294. StartSnd
  295.     lea    DeliPort(pc),a0
  296.     lea    DeliMsg(pc),a1
  297.     move.l    #PlayerPort,MN_REPLYPORT(a1)
  298.     move.w    #dpm_SIZEOF,MN_LENGTH(a1)
  299.     move.l    #StartSound,dpm_Command(a1)
  300.     CALLEXEC PutMsg
  301.  
  302.     lea    PlayerPort(pc),a0
  303.     CALLEXEC WaitPort            ; Schlaf gut
  304.  
  305.     lea    PlayerPort(pc),a0
  306.     CALLEXEC GetMsg
  307.     rts
  308.  
  309. *-----------------------------------------------------------------------*
  310. ;
  311. ; Stop Sound
  312.  
  313. StopSnd
  314.     lea    DeliPort(pc),a0
  315.     lea    DeliMsg(pc),a1
  316.     move.l    #PlayerPort,MN_REPLYPORT(a1)
  317.     move.w    #dpm_SIZEOF,MN_LENGTH(a1)
  318.     move.l    #StopSound,dpm_Command(a1)
  319.     CALLEXEC PutMsg
  320.  
  321.     lea    PlayerPort(pc),a0
  322.     CALLEXEC WaitPort            ; Schlaf gut
  323.  
  324.     lea    PlayerPort(pc),a0
  325.     CALLEXEC GetMsg
  326.     rts
  327.  
  328. *-----------------------------------------------------------------------*
  329. ;
  330. ; Set Volume & Balance
  331.  
  332. SetVol
  333.     move.w    dtg_SndLBal(a5),d0
  334.     mulu    dtg_SndVol(a5),d0
  335.     lsr.w    #6,d0
  336.     move.w    d0,p_l_vol            ; Left Volume
  337.  
  338.     move.w    dtg_SndRBal(a5),d0
  339.     mulu    dtg_SndVol(a5),d0
  340.     lsr.w    #6,d0
  341.     move.w    d0,p_r_vol            ; Right Volume
  342.  
  343.     lea    DeliPort(pc),a0
  344.     lea    DeliMsg(pc),a1
  345.     move.l    #PlayerPort,MN_REPLYPORT(a1)
  346.     move.w    #dpm_SIZEOF,MN_LENGTH(a1)
  347.     move.l    #SetVolume,dpm_Command(a1)
  348.     CALLEXEC PutMsg
  349.  
  350.     lea    PlayerPort(pc),a0
  351.     CALLEXEC WaitPort            ; Schlaf gut
  352.  
  353.     lea    PlayerPort(pc),a0
  354.     CALLEXEC GetMsg
  355.     rts
  356.  
  357. *-----------------------------------------------------------------------*
  358. ;
  359. ; Player Process
  360.  
  361.     cnop 0,4                ; Align to longword
  362. PlayerProc
  363.     dc.l    16                ; Segment "length" (faked)
  364.     dc.l    0                ; Pointer to next segment
  365.  
  366. Begin
  367.     lea    DeliPort(pc),a0            ; init Port
  368.     clr.l    LN_SUCC(a0)
  369.     clr.l    LN_PRED(a0)
  370.     move.b    #NT_MSGPORT,LN_TYPE(a0)
  371.     clr.b    LN_PRI(a0)
  372.     move.l    #DeliPortName,LN_NAME(a0)
  373.     move.b    #PA_SIGNAL,MP_FLAGS(a0)
  374.  
  375.     moveq    #-1,d0
  376.     CALLEXEC AllocSignal            ; Signalbit für DeliPort besorgen
  377.     lea    DeliPort(pc),a1            ; ^Port
  378.     move.b    d0,MP_SIGBIT(a1)
  379.     move.l    ThisTask(a6),MP_SIGTASK(a1)    ; copy ^ThisTask
  380.     CALLEXEC AddPort            ; MsgPort anlegen
  381.  
  382.     lea    AudioPort(pc),a0        ; init Port
  383.     clr.l    LN_SUCC(a0)
  384.     clr.l    LN_PRED(a0)
  385.     move.b    #NT_MSGPORT,LN_TYPE(a0)
  386.     clr.b    LN_PRI(a0)
  387.     move.l    #AudioPortName,LN_NAME(a0)
  388.     move.b    #PA_SIGNAL,MP_FLAGS(a0)
  389.  
  390.     lea    IORequest(pc),a0        ; init IORequest
  391.     clr.l    LN_SUCC(a0)
  392.     clr.l    LN_PRED(a0)
  393.     clr.b    LN_TYPE(a0)
  394.     move.b    #ADALLOC_MAXPREC,LN_PRI(a0)
  395.     clr.l    LN_NAME(a0)
  396.     move.l    #AudioPort,MN_REPLYPORT(a0)
  397.  
  398.     moveq    #-1,d0
  399.     CALLEXEC AllocSignal            ; Signalbit für AudioPort besorgen
  400.     lea    AudioPort(pc),a1        ; ^Port
  401.     move.b    d0,MP_SIGBIT(a1)    
  402.     move.l    ThisTask(a6),MP_SIGTASK(a1)    ; copy ^ThisTask
  403.     CALLEXEC AddPort            ; MsgPort für AudioDevice anlegen
  404.  
  405.     moveq    #0,d0                ; AudioDevice öffnen
  406.     moveq    #0,d1                
  407.     lea    audioname(pc),a0
  408.     lea    IORequest(pc),a1        ; IORequeststruktur
  409.  
  410.     clr.l    IO_UNIT(a1)            ; (re-)init structure
  411.     move.w    #ADCMD_ALLOCATE,IO_COMMAND(a1)
  412.     move.b    #ADIOF_NOWAIT,IO_FLAGS(a1)
  413.     clr.b    IO_ERROR(a1)
  414.     move.l    #ChannelMap,ioa_Data(a1)
  415.     move.l    #4,ioa_Length(a1)
  416.     clr.w    ioa_Period(a1)
  417.     clr.w    ioa_Volume(a1)
  418.     clr.w    ioa_Cycles(a1)
  419.  
  420.     CALLEXEC OpenDevice
  421.  
  422.     lea    DeliMsg(pc),a0            ; Message
  423.     clr.l    MN_REPLYPORT(a0)
  424.     move.w    #dpm_SIZEOF,MN_LENGTH(a0)
  425.     move.l    d0,dpm_UserData(a0)        ; set retunvalue
  426.  
  427.     lea    IORequest(pc),a0        ; IORequeststruktur
  428.     move.l    IO_UNIT(a0),p_chmap        ; store Channelmap
  429.  
  430.     lea    AudioPort(pc),a1        ; Audio Port
  431.  
  432.     move.l    IO_DEVICE(a0),d0        ; get ^Device & AllocKey
  433.     move.w    ioa_AllocKey(a0),d1
  434.  
  435.     lea    IORequest1a(pc),a0
  436.     bsr    InitIORequest            ; IORequest 1a
  437.  
  438.     lea    IORequest1b(pc),a0
  439.     bsr    InitIORequest            ; IORequest 1b
  440.  
  441.     lea    IORequest2a(pc),a0
  442.     bsr    InitIORequest            ; IORequest 2a
  443.  
  444.     lea    IORequest2b(pc),a0
  445.     bsr    InitIORequest            ; IORequest 2b
  446.  
  447.     move.l    #3579547,d0            ; copy & convert chk values
  448.     divu    s_speed,d0
  449.     move.w    d0,p_speed
  450.     move.l    s_size,p_size
  451.     move.l    s_chan1,p_chan1
  452.     move.l    s_chan2,p_chan2
  453.  
  454.     move.w    #-1,QuitFlag            ; kein Ende
  455.     move.w    #-1,p_pause            ; paused
  456.  
  457.     lea    PlayerPort(pc),a0
  458.     lea    DeliMsg(pc),a1            ; Message
  459.     CALLEXEC PutMsg                ; player is ready !
  460.  
  461.     lea    DeliMsg(pc),a0
  462.     tst.l    dpm_UserData(a0)        ; initialisation error ?
  463.     bne    NoAudioDev            ; yes !
  464.  
  465. ;--------------------------------------------------------------------------
  466. ;
  467. ; Hauptschleife
  468.  
  469. MainLoop
  470.     bsr    PlaySample
  471.  
  472.     moveq    #0,d0                ; clear WaitMask
  473.  
  474.     lea    AudioPort(pc),a0
  475.     move.b    MP_SIGBIT(a0),d1        ; AudioMask holen
  476.     bset.l    d1,d0
  477.  
  478.     lea    DeliPort(pc),a0
  479.     move.b    MP_SIGBIT(a0),d1        ; DeliMask holen
  480.     bset.l    d1,d0
  481.  
  482.     CALLEXEC Wait                ; Schlaf gut
  483.  
  484. AudioCollect                    ; collects Write msg's
  485.     lea    AudioPort(pc),a0
  486.     CALLEXEC GetMsg
  487.     tst.l    d0                ; Msg da ?
  488.     beq.s    DeliCollect            ; Nein !
  489.     subq.w    #1,p_wmsg            ; Messagecounter - 1
  490.     bra.s    AudioCollect
  491.  
  492. DeliCollect                    ; collects DeliTracker msg's
  493.     lea    DeliPort(pc),a0
  494.     CALLEXEC GetMsg
  495.     tst.l    d0                ; Msg da ?
  496.     beq.s    DeliSelect            ; Nein !
  497.     move.l    d0,-(sp)            ; store ^Msg
  498.     move.l    d0,a0
  499.     move.l    dpm_Command(a0),a0        ; CMD
  500.     jsr    (a0)                ; Befehl ausführen
  501.     move.l    (sp)+,a1            ; restore ^Msg
  502.     CALLEXEC ReplyMsg            ; return to sender
  503.     bra.s    DeliCollect
  504.  
  505. DeliSelect
  506.     tst.w    QuitFlag            ; schon Ende ?
  507.     bne.s    MainLoop            ; noch nicht !
  508.  
  509. ;--------------------------------------------------------------------------
  510. ;
  511. ; quit Player
  512.  
  513. Quit
  514.     lea    IORequest(pc),a1        ; Audio Device schließen
  515.     CALLEXEC CloseDevice
  516. NoAudioDev
  517.     lea    AudioPort(pc),a1
  518.     CALLEXEC RemPort            ; MsgPort für AudioDevice entfernen
  519.     lea    AudioPort(pc),a1
  520.     move.b    MP_SIGBIT(a1),d0
  521.     CALLEXEC FreeSignal            ; Signalbit für AudioPort freigeben
  522.  
  523.     lea    DeliPort(pc),a1
  524.     CALLEXEC RemPort            ; MsgPort entfernen
  525.     lea    DeliPort(pc),a1
  526.     move.b    MP_SIGBIT(a1),d0
  527.     CALLEXEC FreeSignal            ; Signalbit für DeliPort freigeben
  528.  
  529.     rts                    ; Playerprozess beenden
  530.  
  531. ;--------------------------------------------------------------------------
  532. ;
  533. ; End Player
  534.  
  535. EndPlayer
  536.     clr.w    QuitFlag            ; Player beenden
  537.     rts
  538.  
  539. ;--------------------------------------------------------------------------
  540. ;
  541. ; Init IORequest
  542. ;
  543. ; in: a0:^iorequest
  544. ;     a1:^port
  545. ;     d0:Device
  546. ;     d1:AllocKey
  547.  
  548. InitIORequest
  549.     move.b    #ADALLOC_MAXPREC,LN_PRI(a0)
  550.     clr.l    LN_NAME(a0)
  551.     move.l    a1,MN_REPLYPORT(a0)
  552.     move.l    d0,IO_DEVICE(a0)
  553.     clr.l    IO_UNIT(a0)
  554.     clr.w    IO_COMMAND(a0)
  555.     clr.b    IO_FLAGS(a0)
  556.     clr.b    IO_ERROR(a0)
  557.     move.w    d1,ioa_AllocKey(a0)
  558.     clr.l    ioa_Data(a0)
  559.     clr.l    ioa_Length(a0)
  560.     clr.w    ioa_Period(a0)
  561.     clr.w    ioa_Volume(a0)
  562.     clr.w    ioa_Cycles(a0)
  563.     rts
  564.  
  565. *-----------------------------------------------------------------------*
  566. ;
  567. ; Start Sound
  568.  
  569. StartSound
  570.     tst.w    p_pause                ; playing/paused ?
  571.     beq.s    StSnd_End            ; playing !
  572.  
  573.     clr.w    p_pause                ; playing
  574.     clr.l    p_pos                ; start from begin
  575.  
  576.     lea    IORequest(pc),a1
  577.     move.l    p_chmap(pc),IO_UNIT(a1)        ; stop both channels
  578.     move.w    #CMD_STOP,IO_COMMAND(a1)
  579.     move.b    #IOF_QUICK,IO_FLAGS(a1)
  580.     BEGINIO                    ; execute command
  581.  
  582.     bsr    SetVolume            ; Lautstärke setzen
  583.  
  584.     bsr    DoubleBuff            ; Sound zweimal starten
  585.     bsr    DoubleBuff            ; (wegen Double Buffering)
  586.  
  587.     lea    IORequest(pc),a1
  588.     move.l    p_chmap(pc),IO_UNIT(a1)        ; start both channels
  589.     move.w    #CMD_START,IO_COMMAND(a1)
  590.     move.b    #IOF_QUICK,IO_FLAGS(a1)
  591.     BEGINIO                    ; execute command
  592. StSnd_End
  593.     rts
  594.  
  595. *-----------------------------------------------------------------------*
  596. ;
  597. ; Plays the Sample
  598.  
  599. PlaySample
  600.     tst.w    p_pause                ; playing/paused ?
  601.     bne    PlSam_End            ; paused !
  602.  
  603.     tst.w    p_wmsg                ; all write msg's replied ?
  604.     bgt    PlSam_End            ; no !
  605.  
  606.     tst.l    p_endpos            ; songend reached ?
  607.     bne.s    DoubleBuff            ; no !
  608.     move.l    SongendPtr(pc),a0
  609.     jsr    (a0)                ; signal songend to DeliTracker
  610. DoubleBuff
  611.     move.w    #2,p_wmsg            ; 2 write msg's are pending
  612.  
  613.     move.l    p_size(pc),d0
  614.     sub.l    p_pos(pc),d0
  615.     cmpi.l    #128*1024,d0
  616.     ble.s    SmallSample
  617.     move.l    #128*1024,d0
  618. SmallSample
  619.     move.l    d0,p_len
  620.  
  621.     move.l    p_ioreq1(pc),a1
  622.     move.l    p_chmap(pc),d0
  623.     andi.l    #Left_0!Left_3,d0
  624.     move.l    d0,IO_UNIT(a1)            ; Channel 1
  625.     move.w    #CMD_WRITE,IO_COMMAND(a1)
  626.     move.b    #IOF_QUICK,IO_FLAGS(a1)
  627.     move.l    p_chan1(pc),d0
  628.     add.l    p_pos(pc),d0
  629.     move.l    d0,ioa_Data(a1)
  630.     move.l    p_len(pc),ioa_Length(a1)
  631.     move.w    #1,ioa_Cycles(a1)
  632.     BEGINIO                    ; execute command
  633.  
  634.     move.l    p_ioreq1(pc),d0            ; swap ^ioreq
  635.     move.l    p_ioreq1b(pc),p_ioreq1
  636.     move.l    d0,p_ioreq1b
  637.  
  638.     move.l    p_ioreq2(pc),a1
  639.     move.l    p_chmap(pc),d0
  640.     andi.l    #Right_1!Right_2,d0
  641.     move.l    d0,IO_UNIT(a1)            ; Channel 2
  642.     move.w    #CMD_WRITE,IO_COMMAND(a1)
  643.     move.b    #IOF_QUICK,IO_FLAGS(a1)
  644.     move.l    p_chan2(pc),d0
  645.     add.l    p_pos(pc),d0
  646.     move.l    d0,ioa_Data(a1)
  647.     move.l    p_len(pc),ioa_Length(a1)
  648.     move.w    #1,ioa_Cycles(a1)
  649.     BEGINIO                    ; execute command
  650.  
  651.     move.l    p_ioreq2(pc),d0            ; swap ^ioreq
  652.     move.l    p_ioreq2b(pc),p_ioreq2
  653.     move.l    d0,p_ioreq2b
  654.  
  655.     move.l    p_pos(pc),p_endpos
  656.  
  657.     move.l    p_len(pc),d0
  658.     add.l    p_pos(pc),d0
  659.     cmp.l    p_size(pc),d0
  660.     blt.s    NextSampleBlock
  661.     moveq    #0,d0
  662. NextSampleBlock
  663.     move.l    d0,p_pos
  664.  
  665. PlSam_End
  666.     rts
  667.  
  668. *-----------------------------------------------------------------------*
  669. ;
  670. ; Stop Sound
  671.  
  672. StopSound
  673.     tst.w    p_pause                ; playing/paused ?
  674.     bne.s    SpSnd_End            ; paused !
  675.  
  676.     move.w    #-1,p_pause            ; paused
  677.  
  678.     lea    IORequest(pc),a1
  679.     move.l    p_chmap(pc),IO_UNIT(a1)        ; both Channels
  680.     move.w    #CMD_FLUSH,IO_COMMAND(a1)
  681.     move.b    #IOF_QUICK,IO_FLAGS(a1)
  682.     BEGINIO                    ; execute command
  683. SpSnd_End
  684.     rts
  685.  
  686. *-----------------------------------------------------------------------*
  687. ;
  688. ; Set Volume & Balance
  689.  
  690. SetVolume
  691.     tst.w    p_pause                ; playing/paused ?
  692.     bne.s    StVol_End            ; paused !
  693.  
  694.     lea    IORequest(pc),a1
  695.     move.l    p_chmap(pc),d0
  696.     andi.l    #Left_0!Left_3,d0
  697.     move.l    d0,IO_UNIT(a1)            ; Channel 1
  698.     move.w    #ADCMD_PERVOL,IO_COMMAND(a1)
  699.     move.b    #IOF_QUICK,IO_FLAGS(a1)
  700.     move.w    p_speed(pc),ioa_Period(a1)
  701.     move.w    p_l_vol(pc),ioa_Volume(a1)    ; Left Volume
  702.     BEGINIO                    ; execute command
  703.  
  704.     lea    IORequest(pc),a1
  705.     move.l    p_chmap(pc),d0
  706.     andi.l    #Right_1!Right_2,d0
  707.     move.l    d0,IO_UNIT(a1)            ; Channel 2
  708.     move.w    #ADCMD_PERVOL,IO_COMMAND(a1)
  709.     move.b    #IOF_QUICK,IO_FLAGS(a1)
  710.     move.w    p_speed(pc),ioa_Period(a1)
  711.     move.w    p_r_vol(pc),ioa_Volume(a1)    ; Right Volume
  712.     BEGINIO                    ; execute command
  713. StVol_End
  714.     rts
  715.  
  716. *-----------------------------------------------------------------------*
  717.  
  718.